/*
 * @Author: fhw
 * @Date: 2022-07-01 15:39:20
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2023-03-29 13:40:23
 * @Description:
 */
import { defineComponent, PropType, ref } from 'vue'
import { CloudUploadOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { equals, isNil } from 'ramda'
import { errorTips } from '@/utils'
import { AilOSS, isFileSizeExceeding50MB, OssData } from '@/utils/upload'
import { bytesToMb, isTrue } from '@/utils/tools'
export interface FileInfo {
	file: Blob
	fileList: FileItem[]
}

interface FileItem {
	uid: string
	name?: string
	status?: string
	response?: string
	url?: string
	type?: string
	size: number
	originFileObj: any
}
const props = {
	accept: {
		type: String as PropType<string>,
		default: '.jpg,.png,.jpeg',
	},
	src: {
		type: String as PropType<string>,
		default: '',
	},
	style: {
		type: [String, Object] as PropType<string | object | any>,
		default: '',
	},
	/** 上传oss文件夹名称 */
	folder: {
		type: String as PropType<string>,
	},
	disabled: {
		type: Boolean,
		default: false
	}
} as const
export default defineComponent({
	emits: ['change', 'update:src'],
	props,
	setup(props, { emit, slots }) {
		const loading = ref(false)
		const OSS = AilOSS
		const LoadingKey = 'upload';
		const isFileSize100MB = ref(false)
		const progressNum = ref(0)
		async function handleChange(info: FileInfo) {
			if (!equals(props.accept, '*') && isTrue(props.accept)) {
				const reg = props.accept.split(',').map(ext => ext.trim().replace(/\.[^.]+$/, match => match.replace('.', ''))).join('|')
				if (!new RegExp(`\\.(${reg})$`, 'i').test((info.file as any).name.toLowerCase())) {
					message.error(`上传格式不正确，请上传${props.accept}格式`)
					return false
				}
			}
			const curFiles = info.file as File
			try {
				loading.value = true
				message.loading({ content: 'Loading...', key: LoadingKey });
				isFileSize100MB.value = isFileSizeExceeding50MB(curFiles)
				const data = await OSS.uploadOSS(curFiles, props.folder, (p) => {
					progressNum.value = Number((p * 100).toFixed(2))
				})
				message.success({ content: '上传成功', key: LoadingKey });
				loading.value = false
				const extension = curFiles.name.split('.').pop()?.toLowerCase();
				/** 待重构 */
				if (['jpg', 'jpeg', 'png', 'gif'].includes(extension as string)) {
					const imageUrl = URL.createObjectURL(curFiles); // 生成临时URL地址
					const imgElement = new Image();
					imgElement.src = imageUrl;
					imgElement.onload = () => {
						// 如果想进行更多操作或者显示到页面上，可以根据需求修改下面的代码
						emit('change', {
							...data,
							byte: bytesToMb(curFiles.size),
							size: `${imgElement.width}x${imgElement.height}`,
							width: imgElement.width,
							height: imgElement.height,
						} as OssData)
					};
				} else if (['mp4', 'avi', 'mkv', 'wmv', 'flv', 'mov', 'webm'].includes(extension as string)) {
					const file = {
						...data,
						type: curFiles.type,
						byte: bytesToMb(curFiles.size),
					}
					emit('change', file as OssData)
				} else if (['pdf'].includes(extension as string)) {
					const file = {
						...data,
						type: curFiles.type,
						byte: bytesToMb(curFiles.size),
					}
					emit('change', file as OssData)
				}
				if (data.url) {
					emit('update:src', data.url)
				}

			} catch (error) {
				loading.value = false
				errorTips('上传文件失败:' + error)
			}

		}
		return () => (
			<div>
				<a-spin spinning={loading.value} tip="上传中...">
					<a-upload
						disabled={props.disabled}
						name="avatar"
						list-type="picture-card"
						class="avatar-uploader"
						show-upload-list={false}
						before-upload={() => false}
						onChange={handleChange}
						accept={props.accept}
					>
						{slots.default ? (
							slots.default?.()
						) : props.src ? (
							<div style={props.style} class="flexBox">
								<img src={props.src} alt="" style="width: 100%" />
							</div>
						) : (
							<p class="ant-upload-drag-icon flexBox" style={props.style}>
								<CloudUploadOutlined style="font-size: 40px;color:#40a9ff" />
							</p>
						)}
					</a-upload>
				</a-spin>
				{
					isFileSize100MB.value && (
						<a-progress percent={progressNum.value} />
					)
				}
			</div>
		)
	},
})
